# -*- coding: utf-8  -*-
#!/usr/local/bin/python

__author__ = 'jian.yao'

from django.template import loader
from django.http import HttpResponse
from django.utils import simplejson
from django.utils.cache import patch_response_headers
from misc.errorcode import ERROR_CODE, ERROR_MESSAGE
from configuration.version import VERSION, BUILD
from misc import data_compress, timestamp, long_to_bytes
from misc.xml2json import xml2json
from misc.crypt import cryptString, decryptString
from configuration.appserver_conf import AppServerConf, SITE_APP_SERVER_DICT

def crypt_buffer(_buffer, **_kwargs):
    _cryct = _kwargs.get("_crypt", False)
    _mimetype = ""
    if _cryct:
        _server_id = _kwargs.get("_server_id", None)
        if _server_id:
            _server = AppServerConf.get(_value = _server_id, _key = "id")
            _secret = _server.get("_secret_key")
            _buffer = cryptString(_secret, _buffer)
            _mimetype = "text/plain"
        else:
            pass
    return _buffer, _mimetype

def decrypt_buffer(_buffer, **_kwargs):
    _secret = _kwargs.get("_secret", None)
    if not _secret:
        _secret = SITE_APP_SERVER_DICT.get("secret_key", "")
    if _secret:
        _buffer = decryptString(_secret, _buffer)
    return _buffer

def compress_response(_buffer):
    _length, _compressed = data_compress(_buffer)
    response = HttpResponse(mimetype = 'application/octet-stream')
    response.write(long_to_bytes(_length, 10))
    response.write(_compressed)
    return response

def compile_response(request, _template, _context, _force_compress = False, **_kwargs):
    request.CUSTOM_VARY = True

    _context.update({"version" : "%s-%s" % (VERSION, BUILD)})
    _context.update({"timestamp" : timestamp()})

    if ('output' in _kwargs) and (_kwargs['output'] is not None):
        _outfmt = _kwargs['output'].lower()
    else:
        _outfmt = request.parameters.get("output", None) or "xml"
        if _outfmt:
            _outfmt = _outfmt.lower()

    if _outfmt not in ["xml", "json", "jsonp", "json2", "jsonp2"]:
        _outfmt = "xml"
    _channel = request.parameters.get("channel", "")
    if _channel == "tizen":
        if _outfmt == "json":
            _outfmt = "json2"
        elif _outfmt == "jsonp":
            _outfmt = "json2"

    if ('compress' in _kwargs) and (_kwargs['compress'] is not None):
        _compress = _kwargs['compress'].lower()
    else:
        _compress = request.parameters.get("compress", None) or "false"
        if _compress:
            _compress = _compress.lower()
    if _force_compress or _force_compress == "true":
        _compress = True
    else:
        _compress = False

    if('callback' in _kwargs) and (_kwargs['callback'] is not None):
        _callback = _kwargs['callback']
    else:
        _callback = request.parameters.get("callback", "callback")

    if _outfmt == "xml":
        _buffer = loader.get_template(_template).render(_context)
        _mimetype = "text/xml"
    elif _outfmt == "json":
        _buffer = loader.get_template(_template[:-4]+".json").render(_context)
        _dict = eval(_buffer)
        _buffer = simplejson.dumps(_dict)
        _mimetype = "application/json"
    elif _outfmt == "json2":
        _temp = loader.get_template(_template).render(_context)
        _buffer = xml2json(_temp, strip = 0)
        _mimetype = "application/json"
    elif _outfmt == "jsonp":
        _temp2 = loader.get_template(_template[:-4]+".json").render(_context)
        if isinstance(_callback, unicode):
            _callback = _callback.encode("utf-8")
        _dict = eval(_temp2)
        _temp2 = simplejson.dumps(_dict)
        _buffer = "%s(%s)" % (_callback, _temp2)
        _mimetype = "text/plain"
    elif _outfmt == "jsonp2":
        _temp1 = loader.get_template(_template).render(_context)
        _temp2 = xml2json(_temp1, strip=0)
        if isinstance(_callback, unicode):
            _callback = _callback.encode("utf-8")
        _buffer = "%s(%s)" % (_callback, _temp2)
        _mimetype = "text/plain"
    else:
        _buffer = "Not Implemented."
        _mimetype = "text/plain"
        _context.update({
            "result" : False,
            "errorcode" : ERROR_CODE.NOT_IMPLEMENTED,
            "message" : ERROR_MESSAGE.NOT_IMPLEMENTED
        })
    _buffer, _new_mimetype = crypt_buffer(_buffer.encode("utf-8"), **_kwargs)
    if _new_mimetype:
        _mimetype = _new_mimetype
    if _compress:
        response = compile_response(_buffer)
    else:
        response = HttpResponse(_buffer, mimetype=_mimetype)

    patch_response_headers(response, 0)
    return response



